package ministock;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentMap;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import weibo4j.Comment;
import weibo4j.Paging;
import weibo4j.Status;
import weibo4j.WeiboException;

import com.google.code.ministock.Stock;

public class SubscriptionProducer extends Agent {

	private static final Logger logger = LoggerFactory.getLogger(SubscriptionProducer.class);
	
	private static final long SINCE_ID_DATABASE = 3548799683l;

	private long sinceId;

	private Status database;

	public SubscriptionProducer(
			ConcurrentMap<String, List<Subscription>> subscriptionsMap,
			BlockingQueue<Stock> stocks, boolean stopped) {
		super(subscriptionsMap, stocks, stopped);
		initSinceId();
	}

	public static void main(String[] args) {
		SubscriptionProducer sp = new SubscriptionProducer(null, null, false);
		sp.run();
	}
	
	private void initSinceId() {
		try {
			MyWeibo weibo = MyWeibo.getInstance();
			database = weibo.showStatus(SINCE_ID_DATABASE);// hard coded
			List<Comment> comments = weibo.getComments(database.getId() + "");
			sinceId = comments == null || comments.isEmpty() ? SINCE_ID_DATABASE
					: Long.valueOf(comments.get(0).getText());
			logger.info("Initialized by sinceId : {}", sinceId);
		} catch (WeiboException e) {
			e.printStackTrace(System.err);
			System.exit(-1);
		}
	}

	@Override
	public void run() {
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new SubscriptionScanner(), 1000, MiniStock.getSubscriptionScanPeriod());
	}

	private class SubscriptionScanner extends TimerTask {
		@Override
		public void run() {
			try {
				MyWeibo weibo = MyWeibo.getInstance();
				Paging paging = new Paging();
				paging.setSinceId(sinceId);
				boolean changed = false;
				List<Status> statuses = weibo.getMentions(paging);
				if(null != statuses) {
					logger.debug("Received {} new mentions.", statuses.size());
					for (Status status : statuses) {
						sinceId = status.getId();//存时放ID，取时取Text
						process(status);
						changed = true;
					}
					if(changed) {
						weibo.updateComment(sinceId + "", SINCE_ID_DATABASE + "", null);
					}
				}
			} catch (WeiboException e) {
				e.printStackTrace(System.err);
				System.exit(-1);
			}
		}
		
		private void process(Status status) throws WeiboException {
			String text = status.getText();
			String subDB = String.valueOf(MiniStock.SUBSCRIPTION_DATABASE);
			text = text.substring(0, text.indexOf('@'));// 600258, 100003, @微股票 
			logger.info("Manage subscription {} for {}", text, status.getUser().getName());
			String[] stockNames = text.split(",");
			MyWeibo weibo = MyWeibo.getInstance();
			if(stockNames.length > 0) {
				for(String stockName : stockNames) {
					stockName = stockName.trim();
					if(!"".equals(stockName)) {
						boolean subscribe = !stockName.startsWith("-");//false means unsubscribe
						stockName = subscribe ? stockName : stockName.substring(1);
						stockName = decorateStockName(stockName);
						if(null == stockName) {
							continue;//一些回复和评论
						}
						Subscription subscription = new Subscription(String.valueOf(status.getId()), stockName);
						List<Subscription> list = getSubscriptions(stockName);
						String content = subscription.toString();
						if(subscribe) {
							list.add(subscription);
						} else {
							list.remove(subscription);
							content = "-" + content;
						}
						weibo.updateComment(content, subDB, null);
					}
				}
			}
		}

		private String decorateStockName(String stockName) {
			String low = stockName.toLowerCase();
			if(low.startsWith("sh") || low.startsWith("sz")) {
				return low;
			} else {
				if(stockName.length() == 6 && StringUtils.isNumeric(stockName)) {
					return low.startsWith("6") ? "sh" + low : "sz" + low;
				}
			}
			return null;
		}
	}
}
